using System.ServiceModel;
using DotLiquid.Tags;
using HengTong.Kingdee.Connected_Services.WSExportMaterialFacadeSrvProxyService;
using HengTong.Kingdee.Connected_Services.WSExportMaterialGroupFacade;
using HengTong.Kingdee.WSWMSImportBillFacadeSrvProxyService;
using HengTong.Model;
using HengTong.Model.Db.SupplyChain.Material;
using HengTong.Model.Db.SupplyChain.Warehouse;
using HengTong.Model.Interfaces;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Models;

namespace HengTong.Kingdee.Eas;

public class EasDataProvider(ILogger<EasDataProvider> logger, EasLogin login) : IThirdPartyDataProvider
{
    public async Task<SysOrg[]> GetOrgData()
    {
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysOrg>();
        var raw = new List<EasCompanyDataHead>();
        var bosType = "16FD9F90";
        var start = 0;
        var rows = 50;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<EasCompanyDataInfo>();
                logger.LogInformation($"EAS查询公司数据, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询公司数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                //注意这里没有转换默认计量单位, 后续如果需要可以自行增加
                var org = new SysOrg();
                org.Code = element.Number;
                org.Name = element.Name;
                list.Add(org);
            });
        }
        return list.ToArray();
    }

    /// <summary>
    /// 1C2AC868
    /// </summary>
    /// <returns></returns>
    public async Task<SysMeasureUnitGroupView[]> GetMeasureUnitGroupData()
    {
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysMeasureUnitGroupView>();
        var raw = new List<MeasureUnitGroupDataHead>();
        var bosType = "1C2AC868";
        var start = 0;
        var rows = 50;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<MeasureUnitGroupDataInfo>();
                logger.LogInformation($"EAS查询计量单位组数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询计量单位分组数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                //注意这里没有转换默认计量单位, 后续如果需要可以自行增加
                var group = new SysMeasureUnitGroupView();
                group.ErpId = element.Number;
                group.Name = element.Name;
                group.Level = element.Level;
                group.Description = element.Description;
                //父级设定到名称中, 调用者需要自动转换到对应的系统数据中
                group.ParentName = element.Parent;
                list.Add(group);
            });
        }
        return list.ToArray();
    }

    /// <summary>
    /// 获取计量单位分组数据
    /// 5B825C57
    /// </summary>
    /// <returns></returns>
    public async Task<SysMeasureUnitView[]> GetMeasureUnitData()
    {
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysMeasureUnitView>();
        var raw = new List<MeasureUnitDataHead>();
        var bosType = "5B825C57";
        var start = 0;
        var rows = 200;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<MeasureUnitDataInfo>();
                logger.LogInformation($"EAS查询计量单位数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询计量单位数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                var group = new SysMeasureUnitView();
                group.ErpId = element.Number;
                group.Name = element.Name;
                group.Description = element.Description;
                //分组信息记录到 GroupName, 调用者需要自动转换到对应的系统数据中
                group.GroupName = element.MeasureUnitGroup;
                list.Add(group);
            });
        }
        return list.ToArray();
    }
    
    /// <summary>
    /// 同步物料分组数据
    /// C79FC042
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<SysMaterialGroupView[]> GetMaterialGroupData()
    {
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysMaterialGroupView>();
        var raw = new List<MaterialGroupDataHead>();
        var bosType = "C79FC042";
        var start = 0;
        var rows = 200;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<MaterialGroupDataInfo>();
                logger.LogInformation($"EAS查询计量单位组数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询计量单位分组数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                //注意这里没有转换默认计量单位, 后续如果需要可以自行增加
                var group = new SysMaterialGroupView();
                group.ErpId = element.Number;
                group.Name = element.Name;
                group.Description = element.Description;
                group.Level = element.Level;
                //父级设定到名称中, 调用者需要自动转换到对应的系统数据中
                group.ParentName = element.Parent;
                list.Add(group);
            });
        }
        return list.ToArray();
    }

    /// <summary>
    /// 4409E7F0
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<SysRawMaterial[]> GetMaterial()
    {
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysRawMaterial>();
        var raw = new List<MaterialDataHead>();
        var bosType = "4409E7F0";
        var start = 0;
        var rows = 200;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<MaterialDataInfo>();
                logger.LogInformation($"EAS查询物料数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询计物料数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                //注意这里没有转换默认计量单位, 后续如果需要可以自行增加
                var material = new SysRawMaterial();
                material.Code = element.Number;
                material.Name = element.Name;
                material.Description = element.Description;
                material.Model = element.Model;
                material.UnitCode = element.BaseUnit;
                material.GroupCode = element.MaterialGroup;
                list.Add(material);
            });
        }
        return list.ToArray();
    }

    /// <summary>
    /// 7FAFDF41
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public Task<object> GetCostCenterData()
    {
        throw new NotImplementedException();
    }

    public async Task<SysWarehouse[]> GetWarehouseData()
    {
        var action = "仓库";
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysWarehouse>();
        var raw = new List<EasWarehouseDataHead>();
        var bosType = "BBE9F8AE";
        var start = 0;
        var rows = 200;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<EasWarehouseDataInfo>();
                logger.LogInformation($"EAS查询{action}数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询{action}数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", action, bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                //注意这里没有转换默认计量单位, 后续如果需要可以自行增加
                var warehouse = new SysWarehouse();
                warehouse.Code = element.Number;
                warehouse.Name = element.Name;
                warehouse.Description = element.Description;
                list.Add(warehouse);
            });
        }
        return list.ToArray();
    }
    
    

    public async Task<SysWarehouseLocationView[]> GetWarehouseLocationData()
    {
        var action = "库位";
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysWarehouseLocationView>();
        var raw = new List<EasLocationDataHead>();
        var bosType = "205FF86A";
        var start = 0;
        var rows = 200;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<EasLocationDataInfo>();
                logger.LogInformation($"EAS查询{action}数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询{action}数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", action, bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                //EAS数据转换为系统数据
                //注意这里没有转换默认计量单位, 后续如果需要可以自行增加
                var location = new SysWarehouseLocationView
                {
                    Code = element.Number,
                    Name = element.Name,
                    Description = element.Description,
                    WarehouseCode = element.Warehouse,
                    AreaCode = element.LocationGroup,
                    CommonState = element.State == "1" ? CommonState.启用 : CommonState.禁用
                };
                list.Add(location);
            });
        }
        return list.ToArray();
    }

    /// <summary>
    /// 获取库存数据
    /// </summary>
    /// <returns></returns>
    public async Task<SysWarehouseStockView[]> GetWarehouseStockData()
    {
        var action = "库存";
        var sessionId = await login.GetSessionId();
        //查询数据
        var client = WSWMSImportBillFacadeSrvProxyClient.CreateFromConfiguration();
        //必须初始化 scope, 否则无法添加 header 会抛出对象为空的异常
        _ = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageHeaders.Add(new EasMessageHeader(sessionId));
        var list = new List<SysWarehouseStockView>();
        var raw = new List<EasInventoryDataHead>();
        var bosType = "BA8AD747";
        var start = 0;
        var rows = 1000;
        do
        {
            try
            {
                var result = await client.exportDataAsync(bosType, start, rows);
                var data = result.ToDataList<EasInventoryDataInfo>();
                logger.LogInformation($"EAS查询{action}数据成功, 获取到数据:{data.Count}条");
                if (data.Any())
                {
                    data.ForEach(element => raw.Add(element.DataHead));
                }
                if (data.Count != rows || start > 10000) break;
            }
            catch (FaultException e)
            {
                logger.LogError(e, "EAS查询{action}数据失败, 请求信息: bosType:{bosType}, 请求区间: {start}-{end}, 错误信息:{errorMessage}", action, bosType, start, start + rows, e.Message);
                break;
            }
            start += rows;
        } while (true);
        if (raw.Any())
        {
            raw.ForEach(element =>
            {
                if (element.BaseQty > 0)
                {
                    var stock = new SysWarehouseStockView
                    {
                        WarehouseCode = element.Warehouse,
                        LocationCode = element.Location,
                        UnitCode = element.BaseUnit,
                        MaterialCode = element.Material,
                        Quantity = element.BaseQty
                    };
                    try
                    {
                        stock.StoreType = (StoreType)element.StoreType[0];
                    }
                    catch (Exception e)
                    {
                        logger.LogError(e, "存储类型转化失败:{storeType}", element.StoreType);
                        return;
                    }
                    list.Add(stock);
                }
            });
        }
        return list.ToArray();
    }
}